<template>
  <div class="app-library">
    <div class="app-library-info">
      <img
        :src="fullUrl(song.belongsToAlbum.coverImage)"
        importance="high"
      >
      <div class="app-library-info-content">
        <div class="app-library-info-actions">
          <Button
            type="primary"
            shape="circle"
            :icon="isLike?'md-heart':'md-heart-outline'"
            class="like"
            @click="handleLike"
          >
            {{ song.favCount }} 喜欢
          </Button>
          <Button
            type="primary"
            shape="circle"
            icon="md-list"
            class="add"
            @click="handleAdd"
          >
            添加到歌单
          </Button>
          <Button
            type="primary"
            shape="circle"
            icon="md-cloud-upload"
            class="post"
            @click="handlePost"
          >
            我要投稿
          </Button>
        </div>
        <h1 class="app-library-info-title">
          {{ song.title }}
        </h1>
        <!-- <span class="app-library-info-subtitle"></span> -->
        <p class="app-library-info-artists">
          歌手：
          <router-link
            v-for="artist in song.belongsToArtists"
            :key="artist.id"
            :to="getArtistRoute(artist.id)"
          >
            {{ artist.name }}
          </router-link>
        </p>
        <p class="app-library-info-album">
          专辑：
          <router-link :to="getAlbumRoute(song.belongsToAlbum.id)">
            {{ song.belongsToAlbum.title }}
          </router-link>
        </p>
        <p class="app-library-info-publishdate">
          发行日期：{{ song.belongsToAlbum.publishDate }}
        </p>
        <!-- <audio
              controls
              :src="fullUrl(song.audioFile.path)"
              :type="song.audioFile.mimetype"
            /> -->
        <SongPlayer :src="fullUrl(song.audioFile.path)" />
      </div>
    </div>
    <PlayListsSelectorModal
      v-model="isPLSelectorModalActived"
      :user-id="userId"
      @on-selected="handlePLSelected"
    />
    <PostModal
      v-model="isPostModalActived"
      :user-id="userId"
      :song-id="song.id"
      @on-uploaded="handlePostUploaded"
    />
    <Tabs :animated="false">
      <LyricTab>{{ song.lyric?song.lyric:'暂无歌词' }}</LyricTab>
      <ScoreTab :song-id="song.id" />
      <TrackTab :song-id="song.id" />
    </Tabs>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import { CreateQueryParams } from '@nestjsx/crud-request'
import { Song, getSongById, checkFavSong, setFavSong, removeFavSong, addSongToPlayList } from '@/api/resources'
import { LayoutModule, BreadcrumbItem } from '@/store/modules/layout'
import { UserModule } from '@/store/modules/user'
import { cdn } from '@/utils'
import * as _ from 'lodash'
import SongPlayer from './components/SongPlayer.vue'
import PlayListsSelectorModal from './components/PlayListsSelectorModal.vue'
import PostModal from './components/PostModal.vue'
import LyricTab from './tabs/LyricTab.vue'
import ScoreTab from './tabs/ScoreTab.vue'
import TrackTab from './tabs/TrackTab.vue'

@Component({
  name: 'Song',
  components: {
    SongPlayer,
    PlayListsSelectorModal,
    PostModal,
    LyricTab,
    ScoreTab,
    TrackTab
  }
})
export default class extends Vue {
  private params: CreateQueryParams = {
    join: [
      { field: 'audioFile' },
      { field: 'mv' },
      { field: 'belongsToArtists', select: ['id', 'name', 'images'] },
      {
        field: 'belongsToAlbum',
        select: ['id', 'title', 'coverImage', 'publishDate']
      }
    ]
  };

  private breadcrumb: BreadcrumbItem[] = [];
  private song: Partial<Song> = {};
  private isLike = false;
  private isPLSelectorModalActived = false;
  private isPostModalActived = false;
  get userId (): number {
    return Number.parseInt(UserModule.id)
  }

  async created () {
    this.song = (
      await getSongById(this.$route.params.songId, this.params)
    ).data

    this.isLike = UserModule.token !== '' ? (await checkFavSong(this.$route.params.songId)).data : false

    if (this.song.belongsToArtists) {
      const artistCrumb: BreadcrumbItem = {
        icon: 'person',
        title: _.flatMap(this.song.belongsToArtists, artist => {
          return {
            content: artist.name || '未知歌手',
            route: this.$router.resolve({
              name: 'LibraryArtist',
              params: { artistId: artist.id?.toString() || '0' }
            }).location
          }
        })
      }
      this.breadcrumb.push(artistCrumb)
    }
    if (this.song.belongsToAlbum) {
      const albumCrumb: BreadcrumbItem = {
        icon: 'album',
        title: {
          content: this.song.belongsToAlbum.title || '未知专辑',
          route: this.$router.resolve({
            name: 'LibraryAlbum',
            params: { albumId: this.song.belongsToAlbum.id?.toString() || '0' }
          }).location
        }
      }
      this.breadcrumb.push(albumCrumb)
    }
    const albumCrumb: BreadcrumbItem = {
      icon: 'music_note',
      title: {
        content: this.song.title || '未知歌曲',
        route: this.$router.resolve(this.$route.fullPath).location
      }
    }
    this.breadcrumb.push(albumCrumb)

    LayoutModule.SetBreadcrumb(this.breadcrumb)
  }

  private fullUrl (path: string) {
    return cdn(path)
  }

  private getArtistRoute (id: number) {
    return this.$router.resolve({
      name: 'LibraryArtist',
      params: { artistId: id.toString() }
    }).location
  }

  private getAlbumRoute (id: number) {
    return this.$router.resolve({
      name: 'LibraryAlbum',
      params: { albumId: id.toString() }
    }).location
  }

  private async setLikeSong (like = true) {
    const { data } = like
      ? await setFavSong(this.$route.params.songId)
      : await removeFavSong(this.$route.params.songId)
    if (data) {
      _.merge(this.song, data)
      this.isLike = like
    }
  }

  private async handleLike () {
    if (UserModule.token === '') {
      this.$Message.warning('您尚未登录')
      return
    }
    await this.setLikeSong(!this.isLike)
  }

  private handleAdd () {
    if (UserModule.token === '') {
      this.$Message.warning('您尚未登录')
      return
    }
    this.isPLSelectorModalActived = true
  }

  private async handlePLSelected (playListId: number) {
    if (playListId === 0) {
      this.setLikeSong().then(() => {
        this.$Message.success('添加成功！')
        this.isPLSelectorModalActived = false
      })
    } else if (this.song.id) {
      addSongToPlayList(playListId, this.song.id).then(() => {
        this.$Message.success('添加成功！')
        this.isPLSelectorModalActived = false
      }).catch(() => {
        this.$Message.error('操作失败，请稍后再试')
      })
    }
  }

  private handlePost () {
    if (UserModule.token === '') {
      this.$Message.warning('您尚未登录')
      return
    }
    this.isPostModalActived = true
  }

  private handlePostUploaded () {
    location.reload()
  }
}
</script>

<style lang="less" scoped>
@import "../../../styles/theme";

@info-img-size: 20%;
@info-img-size-min: 160px;
@info-img-size-max: 220px;
@title-color: #fff5c3;

.app-library-info {
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;

  > img {
    width: @info-img-size;
    height: @info-img-size;
    min-width: @info-img-size-min;
    min-height: @info-img-size-min;
    max-width: @info-img-size-max;
    max-height: @info-img-size-max;
    border-radius: 20px;
    box-shadow: 6px 6px 6px #202020;
  }

  .app-library-info-content {
    flex-grow: 1;
    padding-left: 2rem;

    .app-library-info-title {
      color: @title-color;
      font-size: 2.5em;
    }

    .app-library-info-artists,
    .app-library-info-album {
      font-size: 1.2em;
      font-weight: bold;
      line-height: 1.5em;
      margin: 8px 0;

      a {
        color: @text-color;
        &::after {
          content: "|";
        }
        &:last-of-type {
          &::after {
            content: none;
          }
        }
      }
    }

    .app-library-info-publishdate {
      margin: 8px 0;
    }

    .app-library-info-actions {
      float: right;
      width: 132px;

      button {
        display: block;
        margin: 8px 0;
        width: 100%;
        text-align: left;
        font-weight: bold;
        &.like {
          background-color: @btn-red;
          border-color: @btn-red;
        }
        &.add {
          background-color: @btn-green;
          border-color: @btn-green;
        }
        &.post {
          background-color: @btn-blue;
          border-color: @btn-blue;
        }
      }
    }
  }
}
</style>
